package com.imy.common.util;

import android.content.Context;
import android.os.Environment;

import com.imy.common.constant.Constant;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.charset.StandardCharsets;
import java.text.DecimalFormat;

public class FileUtils {

    public static boolean copyAssetsToSD(Context context, final String srcPath, final String sdPath) {
        return copyAssetsToDst(context, srcPath, sdPath);
    }

    private static boolean copyAssetsToDst(Context context, String srcPath, String dstPath) {
        try {
            String[] fileNames = context.getAssets().list(srcPath);
            if (fileNames == null) {
                return false;
            }
            if (fileNames.length > 0) {
                File file = new File(Environment.getExternalStorageDirectory(), dstPath);
                if (!file.exists()) file.mkdirs();
                for (String fileName : fileNames) {
                    if (!srcPath.equals("")) { // assets 文件夹下的目录
                        copyAssetsToDst(context, srcPath + File.separator + fileName, dstPath + File.separator + fileName);
                    } else { // assets 文件夹
                        copyAssetsToDst(context, fileName, dstPath + File.separator + fileName);
                    }
                }
            } else {
                File outFile = new File(Environment.getExternalStorageDirectory(), dstPath);
                InputStream is = context.getAssets().open(srcPath);
                FileOutputStream fos = new FileOutputStream(outFile);
                byte[] buffer = new byte[1024];
                int byteCount;
                while ((byteCount = is.read(buffer)) != -1) {
                    fos.write(buffer, 0, byteCount);
                }
                fos.flush();
                is.close();
                fos.close();
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }

    }

    /**
     * 复制单个文件
     *
     * @param oldPath$Name String 原文件路径+文件名 如：data/user/0/com.test/files/abc.txt
     * @param newPath$Name String 复制后路径+文件名 如：data/user/0/com.test/cache/abc.txt
     * @return <code>true</code> if and only if the file was copied;
     * <code>false</code> otherwise
     */
    public static boolean copyFile(String oldPath$Name, String newPath$Name) {
        try {
            File oldFile = new File(oldPath$Name);
            ALog.ti("exists" + oldFile.exists() + " " +
                    "isFile:" + oldFile.isFile() + " canRead:" + oldFile.canRead());
            if (!oldFile.exists()) {
                return false;
            } else if (!oldFile.isFile()) {
                return false;
            } else if (!oldFile.canRead()) {
                return false;
            }
            /* 如果不需要打log，可以使用下面的语句
            if (!oldFile.exists() || !oldFile.isFile() || !oldFile.canRead()) {
                return false;
            }
            */
            FileInputStream fileInputStream = new FileInputStream(oldPath$Name);
            FileOutputStream fileOutputStream = new FileOutputStream(newPath$Name);
            byte[] buffer = new byte[1024];
            int byteRead;
            while (-1 != (byteRead = fileInputStream.read(buffer))) {
                fileOutputStream.write(buffer, 0, byteRead);
            }
            fileInputStream.close();
            fileOutputStream.flush();
            fileOutputStream.close();
            return true;
        } catch (Exception e) {
            ALog.ti("msg:" + e.getMessage());
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 创建一个文件夹 0/test/1/2/如果前面的文件夹不存在将预先创建前面文件夹
     *
     * @param path
     */
    public static void createFileDir(String path) {
        File externalStorageDirectory = Environment.getExternalStorageDirectory();
        String absolutePath = externalStorageDirectory.getAbsolutePath();
        String substring = path.substring(absolutePath.length() + 1);
        String[] split = substring.split("/");
        String childPath = absolutePath;
        for (int i = 0; i < split.length; i++) {
            childPath = childPath + "/" + split[i];
            createIfNoExit(childPath);
        }
    }

    public static void createIfNoExit(String path) {
        File file = new File(path);
        if (!file.exists()) {
            file.mkdir();
        }
    }

    public static String createRootScreenFilePath() {
        createFileDir(Constant.ROOT_SCREEN_FILE_PATH);
        return Constant.ROOT_SCREEN_FILE_PATH;
    }

    public static String createProjectPath() {
        createFileDir(Constant.PROJECT_PATH);
        return Constant.PROJECT_PATH;
    }


    public static boolean deleteDir(File file) {
        boolean result = false;
        //目录
        if (file.isDirectory()) {
            File[] childrenFiles = file.listFiles();
            for (File childFile : childrenFiles) {
                result = deleteDir(childFile);
                if (!result) {
                    return result;
                }
            }
        }
        //删除 文件、空目录
        result = file.delete();
        return result;
    }

    public static String supplyImageSuffix(String fileName) {
        if (fileName.endsWith(".png") || fileName.endsWith(".jpg")) {
            return fileName;
        }
        fileName = fileName + ".png";
        return fileName;
    }

    public static String getStringForFile(File file) {
        FileInputStream fileInputStream = null;
        InputStreamReader inputStreamReader = null;
        try {
            fileInputStream = new FileInputStream(file);
            inputStreamReader = new InputStreamReader(fileInputStream, StandardCharsets.UTF_8);
            char[] chars = new char[1024];
            StringBuilder content = new StringBuilder();
            while (inputStreamReader.read(chars) > 0) {
                content.append(new String(chars));
            }
            return content.toString();
        } catch (IOException e) {
            ALog.e("getStringForFile  error:" + e.getMessage());
            e.printStackTrace();
        } finally {
            try {
                assert fileInputStream != null;
                fileInputStream.close();
                assert inputStreamReader != null;
                inputStreamReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
        return "";
    }


    public static String getFileSizeString(File file) {
        long fileSize = getFileSize(file);

        return readableFileSize(fileSize);
    }

    private static String readableFileSize(long size) {
        if (size <= 0) return "0";
        final String[] units = new String[]{"B", "KB", "MB", "GB", "TB"};
        int digitGroups = (int) (Math.log10(size) / Math.log10(1024));
        return new DecimalFormat("#,##0.#").format(size / Math.pow(1024, digitGroups)) + " " + units[digitGroups];
    }

    public static long getFileSize(File file) {
        FileInputStream fileInputStream = null;

        try {
            fileInputStream = new FileInputStream(file);
            FileChannel channel = fileInputStream.getChannel();
            return channel.size();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                assert fileInputStream != null;
                fileInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return 0;
    }

    public static void deleteFile(String path) {
        File file = new File(path);
        if (file.exists()) {
            file.delete();
        }
    }

    /**
     * @param file     源文件
     * @param fileName 新的文件名
     * @return
     */
    public static boolean reNameFile(File file, String fileName) {
        String s = file.getParentFile().getAbsolutePath() + "/" + fileName;
        return file.renameTo(new File(s));
    }

    public static boolean saveStringToFile(String content, String path) {
        File file = new File(path);


        try {
            RandomAccessFile rwd = new RandomAccessFile(file, "rwd");
            rwd.seek(0);
            byte[] bytes = content.getBytes(StandardCharsets.UTF_8);
            rwd.write(bytes);
            rwd.close();
            return true;
        } catch (IOException e) {
            ALog.e("更新 文件String 内容失败:" + e.getMessage() + " path:" + path);
            e.printStackTrace();
            return false;
        }
    }
}
